package com.ty.pdm.system.workFlow.listener.common;

import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.AES;
import com.hustcad.plm.pdm.enumeration.model.dto.EnumerationValueDTO;
import com.hustcad.plm.pdm.enumeration.model.dto.HandleEnumItemDTO;
import com.hustcad.plm.pdm.enumeration.model.vo.EnumerationItemHandleVO;
import com.hustcad.plm.pdm.enumeration.model.vo.EnumerationQueryVO;
import com.hustcad.plm.pdm.enumeration.service.TyplmEnumerationItemService;
import com.hustcad.plm.pdm.enumeration.service.TyplmEnumerationService;
import com.hustcad.plm.pdm.flowbusiness.model.entity.FlowObject;
import com.hustcad.plm.pdm.flowbusiness.model.entity.WorkFlowObjectPackage;
import com.hustcad.plm.pdm.form.model.vo.TyplmFormDataVO;
import com.hustcad.plm.pdm.form.service.TyFormDataExtService;
import com.hustcad.plm.pdm.security.util.JwtTokenUtil;
import com.hustcad.plm.pdm.user.service.ErpBomService;
import com.hustcad.plm.pdm.workflow.annotion.CustomListener;
import com.hustcad.plm.pdm.workflow.annotion.CustomListenerField;
import com.hustcad.plm.pdm.workflow.model.entity.WorkFlowContainerView;
import com.hustcad.plm.pdm.workflow.service.TyplmWorkFlowContainerService;
import com.jsyxdl.entity.ProjectCodeDTO;
import com.jsyxdl.k3cloud.listener.K3CloudHttpService;
import com.jsyxdl.k3cloud.utils.SendErpDataUtils;
import com.jsyxdl.service.ProjectCodeService;
import com.ty.basic.entity.IdentifierEntity;
import com.ty.basic.exception.message.SystemErrorCodeEnum;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.impl.el.FixedValue;
import org.jeecg.modules.jmreport.desreport.util.e;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;

import java.math.BigInteger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@CustomListener(
        category = "永续项目编号监听",
        description = "永续项目编号接口"
)
public class ProjectNumberListener implements ExecutionListener {
    private static final Logger log = LoggerFactory.getLogger(ProjectNumberListener.class);
    private static final long serialVersionUID = -9059663559349037414L;

    @CustomListenerField(
            description = "接口地址端口",
            defaultValue = "",
            required = true
    )
    private FixedValue address;

    @CustomListenerField(
            description = "ERP接口编码",
            defaultValue = "",
            required = true
    )
    private FixedValue code;

    @CustomListenerField(
            description = "ERP接口对象",
            defaultValue = "",
            required = true
    )
    private FixedValue erpObject;

    public static String acctID;
    public static String username;
    public static String password;

    public ProjectNumberListener() {

    }

    public void notify(DelegateExecution execution) {
        try {
            String workFlowContainerIdStr = execution.getProcessInstanceBusinessKey();
            BigInteger workFlowContainerId = new BigInteger(workFlowContainerIdStr);
            TyplmWorkFlowContainerService typlmWorkFlowContainerService = SpringUtil.getBean(
                    TyplmWorkFlowContainerService.class);
            if (typlmWorkFlowContainerService != null) {
                WorkFlowContainerView workFlowContainerView = typlmWorkFlowContainerService.getWorkFlowContainerDetailByPrimaryKey(
                        workFlowContainerId);
                if (workFlowContainerView instanceof WorkFlowObjectPackage) {
                    WorkFlowObjectPackage workFlowObjectPackage = (WorkFlowObjectPackage) workFlowContainerView;
                    if (workFlowObjectPackage.getFlowObjectList() != null && workFlowObjectPackage.getFlowObjectList()
                            .size() != 0) {

                        ErpBomService erpBomService=SpringUtil.getBean(ErpBomService.class);
                        if(acctID==null){
                            Map<String,Object> map=new HashMap<>();
                            map.put("title","PLM接口配置");
                            List<Map<String,Object>> list=erpBomService.selectFiguration(map);
                            if(list.size()>0){
                                acctID= (String) list.get(0).get("acctid");
                                username= (String) list.get(0).get("username");
                                password=  AES.decrypt((String) list.get(0).get("password"), "huazPlm@15999899");

                            }
                        }

                        for (int i = 0; i < workFlowObjectPackage.getFlowObjectList().size(); i++) {
                            FlowObject flowObject = workFlowObjectPackage.getFlowObjectList().get(i);
                            String oType = flowObject.getRefObjectOtype();
                            if ("ty.inteplm.form.CTyFormData".equals(oType)) {
                                int result = -1;
                                result = (int) extendedTask(acctID, flowObject);
                                if (result != 1) {
                                    throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException("extendedTask!=1");
                                }
                            }
                        }
                    } else {
                        throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException("FlowObjectList为空");
                    }
                } else {
                    throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException("WorkFlowContainerView 转换失败");
                }
            } else {
                throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(
                        "TyplmWorkFlowContainerService 无法加载");
            }

        } catch (Exception var5) {
            log.error("监听ProjectNumberListener异常：", var5);
            throw var5;
        }
    }

    /***
     * 调用ppm接口在项目库中创建项目
     * @param address ppm 地址与端口
     * @param flowObject 流程数据
     * @return
     */
    public int extendedTask(String address, FlowObject flowObject) {
        ProjectCodeService projectCodeService = SpringUtil.getBean(ProjectCodeService.class);

        TyFormDataExtService tyFormDataExtService = SpringUtil.getBean(TyFormDataExtService.class);
        TyplmFormDataVO formDataVO = tyFormDataExtService.getFormDataDetail(flowObject.getRefObjectOid());

        TyplmEnumerationService typlmEnumerationService = SpringUtil.getBean(TyplmEnumerationService.class);
        EnumerationQueryVO enumerationQueryVO = new EnumerationQueryVO();
        enumerationQueryVO.setSystem(0);

        EnumerationValueDTO projec = null;
        List<EnumerationValueDTO> enumList = typlmEnumerationService.getEnumerationDefList(enumerationQueryVO);
        for (int i = 0; i < enumList.size(); i++) {
            if ("项目编号".equals(enumList.get(i).getName())) {
                projec = enumList.get(i);
            }
        }

        if (projec != null) {
            K3CloudHttpService k3CloudHttpService = SpringUtil.getBean(K3CloudHttpService.class);
            try {

                String projectName = formDataVO.getFormdata().getString("projectName");
                ProjectCodeDTO projectCodeDTO = projectCodeService.queryProjectCodeByProjectName(projectName);

                if (projectCodeDTO != null) {
                    String projectNumber = projectCodeDTO.getProjectNumber();

                    HandleEnumItemDTO handleEnumItemDTO = new HandleEnumItemDTO();
                    handleEnumItemDTO.setDefoid(projec.getOid());
                    EnumerationItemHandleVO enumerationItemHandleVO = new EnumerationItemHandleVO();
                    enumerationItemHandleVO.setDisplayName(formDataVO.getFormdata().getString("projectName"));
                    enumerationItemHandleVO.setDisplayNameCn(formDataVO.getFormdata().getString("projectName"));
                    enumerationItemHandleVO.setInternalName(projectNumber);
                    enumerationItemHandleVO.setName(projectNumber);
                    enumerationItemHandleVO.setState("true");

                    JSONObject projectErp = new JSONObject();
                    projectErp.put("projectGrouping", formDataVO.getFormdata().getString("projectGrouping"));
                    projectErp.put("enumerationItemHandleVO",
                                   JSONObject.parseObject(JSONObject.toJSONString(enumerationItemHandleVO)));

                    JSONObject obj = k3CloudHttpService.plmToK3CloudTaskWorkderByParameter(
                            this.code.getExpressionText(), this.erpObject.getExpressionText(), projectErp);
                    if (obj != null) {
                        JSONObject Result = obj.getJSONObject("Result");
                        if (Result != null) {
                            JSONObject ResponseStatus = Result.getJSONObject("ResponseStatus");
                            if (ResponseStatus.getBooleanValue("IsSuccess") == false) {
                                throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(
                                        ResponseStatus.get("Errors").toString());
                            }
                        } else {
                            return 0;
                        }
                    } else {
                        return 0;
                    }
                    return 1;
                } else {
                    String projectYear = formDataVO.getFormdata().getString("Year");
                    String projectGrouping = formDataVO.getFormdata().getString("projectGrouping");
                    String month = formDataVO.getFormdata().getString("Month");

                    Map<String, Object> map = new HashMap<>();
                    map.put("project", projectGrouping);
                    map.put("projectYear", projectYear);
                    map.put("projectMonth", month);
                    int maxVal = 0;
                    Map<String, Object> maxMap = projectCodeService.existsByProjectYear(map);
                    if (maxMap != null) {
                        if (maxMap.containsKey("serial_number")) {
                            if (maxMap.get("serial_number") != null) {
                                maxVal = (int) maxMap.get("serial_number");
                            }
                        }
                    }

                    String xl = "";
                    int count = 0;
                    count = maxVal;
                    count += 1;
                    if (count < 10) {
                        xl = String.format("0%d", count);
                    } else {
                        xl = String.format("%d", count);
                    }
                    String projectNumber = String.format("%s-%s%s%s", projectGrouping, projectYear, month, xl);

                    TyplmEnumerationItemService typlmEnumerationItemService = SpringUtil.getBean(
                            TyplmEnumerationItemService.class);
                    IdentifierEntity identifierEntity = new IdentifierEntity();
                    identifierEntity.setOid(projec.getOid());
                    List<EnumerationItemHandleVO> projectList = typlmEnumerationItemService.queryEnumerationItemByDefOid(
                            identifierEntity);

                    boolean add = true;
                    for (int i = 0; i < projectList.size(); i++) {
                        if (projectNumber.equals(projectList.get(i).getName())) {
                            add = false;
                            break;
                        }
                    }

                    HandleEnumItemDTO handleEnumItemDTO = new HandleEnumItemDTO();
                    handleEnumItemDTO.setDefoid(projec.getOid());
                    EnumerationItemHandleVO enumerationItemHandleVO = new EnumerationItemHandleVO();
                    enumerationItemHandleVO.setDisplayName(formDataVO.getFormdata().getString("projectName"));
                    enumerationItemHandleVO.setDisplayNameCn(formDataVO.getFormdata().getString("projectName"));
                    enumerationItemHandleVO.setInternalName(projectNumber);
                    enumerationItemHandleVO.setName(projectNumber);
                    enumerationItemHandleVO.setState("true");
                    projectList.add(enumerationItemHandleVO);
                    handleEnumItemDTO.setEnumItemList(projectList);

                    JSONObject projectErp = new JSONObject();
                    projectErp.put("projectGrouping", formDataVO.getFormdata().getString("projectGrouping"));
                    projectErp.put("projectUser", formDataVO.getFormdata().getJSONArray("projectManager")
                            .getJSONObject(0).getString("fullname"));

                    projectErp.put("enumerationItemHandleVO",
                                   JSONObject.parseObject(JSONObject.toJSONString(enumerationItemHandleVO)));

                    JSONObject obj = k3CloudHttpService.plmToK3CloudTaskWorkderByParameter(
                            this.code.getExpressionText(), this.erpObject.getExpressionText(), projectErp);
                    if (obj != null) {
                        JSONObject Result = obj.getJSONObject("Result");
                        if (Result != null) {
                            JSONObject ResponseStatus = Result.getJSONObject("ResponseStatus");
                            if (ResponseStatus.getBooleanValue("IsSuccess") == false) {
                                throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(
                                        ResponseStatus.get("Errors").toString());
                            }
                            if (add) {
                                typlmEnumerationService.handleEnumItemList(handleEnumItemDTO);
                                return extendedTaskPPM(projectNumber, count, formDataVO, address);
                            }

                        } else {
                            return 0;
                        }
                    } else {
                        return 0;
                    }
                    return 1;
                }
            } catch (Exception e) {
                throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(e.getMessage());
            }
        }
        return -1;

    }

    /***
     * 调用ppm接口在项目库中创建项目
     * @param projectNumber 项目号编号
     * @param count  尾号序列
     * @param formDataVO 表单数据
     * @param address ppm 地址与端口
     * @return
     */
    public int extendedTaskPPM(String projectNumber, int count, TyplmFormDataVO formDataVO, String address) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("projectManagerList", new JSONArray());

        jsonObject.put("name", formDataVO.getFormdata().getString("projectName"));
        if ("电机".equals(formDataVO.getFormdata().getString("projectType"))) {
            jsonObject.put("category", "电机项目");
        } else if ("变频器".equals(formDataVO.getFormdata().getString("textarea86755"))) {
            jsonObject.put("category", "变频器项目");
        }
        K3CloudHttpService k3CloudHttpService = SpringUtil.getBean(K3CloudHttpService.class);
        String year = formDataVO.getFormdata().getString("Year");
        String projectGrouping = formDataVO.getFormdata().getString("projectGrouping");
        String month = formDataVO.getFormdata().getString("Month");

        jsonObject.put("projectNumber", projectNumber);
        if (formDataVO.getFormdata().containsKey("scheduledDate")) {
            String startDate = formDataVO.getFormdata().getJSONArray("scheduledDate").getString(0);
            String finishDate = formDataVO.getFormdata().getJSONArray("scheduledDate").getString(1);
            if ("".equals(startDate) == false) {
                jsonObject.put("startDate", String.format("%s 00:00:00", startDate));
                jsonObject.put("finishDate", String.format("%s 00:00:00", finishDate));
            } else {
                Instant instant = Instant.ofEpochMilli(System.currentTimeMillis());
                LocalDateTime date = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                String formattedDate = date.format(formatter);
                jsonObject.put("startDate", String.format("%s 00:00:00", formattedDate));
                jsonObject.put("finishDate", "2099-12-30 00:00:00");

            }
        } else {
            Instant instant = Instant.ofEpochMilli(System.currentTimeMillis());
            LocalDateTime date = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());

            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            String formattedDate = date.format(formatter);
            jsonObject.put("startDate", String.format("%s 00:00:00", formattedDate));
            jsonObject.put("finishDate", "2099-12-30 00:00:00");
        }

        if (formDataVO.getFormdata().containsKey("Duration")) {
            jsonObject.put("contractDuration", formDataVO.getFormdata().getString("Duration"));
        }

        jsonObject.put("phase", formDataVO.getFormdata().getString("Stage"));


        JSONArray projectAdministrator = formDataVO.getFormdata().getJSONArray("projectAdministrator");
        if (projectAdministrator != null && projectAdministrator.size() > 0) {
            jsonObject.put("ownerOID", formDataVO.getFormdata().getJSONArray("projectAdministrator").getJSONObject(0)
                    .getString("oid"));
            jsonObject.put("ownerOTYPE", formDataVO.getFormdata().getJSONArray("projectAdministrator").getJSONObject(0)
                    .getString("otype"));
            jsonObject.put("ownerName", formDataVO.getFormdata().getJSONArray("projectAdministrator").getJSONObject(0)
                    .getString("displayFullName"));
            jsonObject.put("ownerDescription", formDataVO.getFormdata().getJSONArray("projectAdministrator")
                    .getJSONObject(0).getString("displayFullName"));

            jsonObject.put("adminUserOid", formDataVO.getFormdata().getJSONArray("projectAdministrator")
                    .getJSONObject(0).getString("oid"));
            jsonObject.put("adminUserOtype", formDataVO.getFormdata().getJSONArray("projectAdministrator")
                    .getJSONObject(0).getString("otype"));
            jsonObject.put("adminUserName", formDataVO.getFormdata().getJSONArray("projectAdministrator")
                    .getJSONObject(0).getString("displayFullName"));
            jsonObject.put("adminUserDescription", formDataVO.getFormdata().getJSONArray("projectAdministrator")
                    .getJSONObject(0).getString("displayFullName"));

        }
        jsonObject.put("completionStatus", "0");
        jsonObject.put("extProps", "");


        JSONArray jsonArray = new JSONArray();
        JSONArray arr = formDataVO.getFormdata().getJSONArray("projectManager");
        if (arr != null && arr.size() > 0) {
            for (int a = 0; a < arr.size(); a++) {
                JSONObject userObj = new JSONObject();
                userObj.put("oid", arr.getJSONObject(a).getString("oid"));
                jsonArray.add(userObj);
            }

            jsonObject.put("projectManagerList", jsonArray);
        }


        JwtTokenUtil jwtTokenUtil = SpringUtil.getBean(JwtTokenUtil.class);
        UserDetails userDetails = new User(username, password,
                                           new ArrayList<>());
        String token = jwtTokenUtil.generateToken(userDetails);
        String url = address + "/api/pdm/v1/project/formDataCreateProject";
        try {
            JSONObject responseResult = k3CloudHttpService.erpServiceHttpToJSONObject(url, jsonObject, token);
            if (responseResult.containsKey("code")) {
                if ("200".equals(responseResult.getString("code"))) {
                    ProjectCodeDTO projectCodeDTO = new ProjectCodeDTO();
                    projectCodeDTO.setId(UUID.randomUUID().toString());
                    projectCodeDTO.setProjectNumber(projectNumber);
                    projectCodeDTO.setProjectName(jsonObject.getString("name"));
                    projectCodeDTO.setProjectYear(year);
                    projectCodeDTO.setSerialNumber((long) count);
                    projectCodeDTO.setProject(projectGrouping);
                    projectCodeDTO.setProjectMonth(month);
                    ProjectCodeService projectCodeService = SpringUtil.getBean(ProjectCodeService.class);
                    projectCodeService.insertProjectCode(projectCodeDTO);
                    return 1;
                }
            }
        } catch (Exception e) {
            throw SystemErrorCodeEnum.WORK_FLOW_CONTENT_ERROR.getException(e.getMessage());
        }

        return -1;
    }

}
